Інтернаціоналізація
===================

Інтернаціоналізація (скорочено I18N) — процес створення додатку, який може працювати на різних мовах і з різними регіональними особливостями без будь-яких додаткових змін. Для веб-додатків це особливо важливо, оскільки користувач може бути з будь-якої точки світу.

Yii підтримує інтернаціоналізацію на декількох рівнях:

   - Надає регіональні дані для всіх можливих мов та їх варіацій.
   - Сервіс для перекладу повідомлень та файлів.
   - Форматування дат і чисел в залежності від регіональних налаштувань.

У наступних розділах ми розглянемо перераховані можливості більш докладно.

Регіональні налаштування і мова
-------------------------------

Регіональні налаштування — це набір параметрів, які задають мову користувача, країну і будь-які інші спеціальні налаштування інтерфейсу. Зазвичай, налаштування визначаються ідентифікатором, що складається з мови та регіону.
Наприклад, ідентифікатор `en_US` відповідає англійській мові і налаштуванням для США.
В Yii всі ідентифікатори регіональних налаштувань названі одноманітно: `LanguageID` (мова) або `LanguageID_RegionID` (мова_регіон)
в нижньому регістрі. Наприклад: `ru`, `en_us`.

Регіональні налаштування зберігаються в обʼєкті класу [CLocale], який можна використовувати для отримання залежної від них інформації, такої як символи і формати валют і чисел, формати дат і часу, назва місяців і днів тижня.
Так що інформація про мову вже міститься в ідентифікаторі, в [CLocale] вона не дублюється.
З цієї причини ми часто застосовуємо в одному контексті терміни «локаль» та «мова».

Маючи ідентифікатор мови, ми можемо отримати відповідний йому обʼєкт [CLocale]:
`CLocale::getInstance($localeID)` або `CApplication::getLocale($localeID)`.

> Info|Інформація: до складу Yii включені регіональні дані практично по всіх мов і регіонам. Дані отримані з
[Common Locale Data Repository](http://unicode.org/cldr/) (CLDR). 
Доступні не всі дані, надані CLDR, так як там міститься велика кількість рідко використовуваної інформації.
Користувачі також можуть надавати свої власні спеціальні регіональні дані.
Для цього налаштуйте властивість [CApplication::localeDataPath], щоб воно вказувало на директорію, 
що містить спеціальні регіональні дані. Зверніться до файлів регіональних даних в директорії 
`framework/i18n/data` для того, щоб створити файли спеціальних регіональних даних.

У додатку Yii ми розрізняємо [мову додатка|CApplication::language] та [вихідну мову додатка|CApplication::sourceLanguage].
Мова додатка — це мова (локаль) користувача, який працює з додатком. Вихідна мова додатка — мова, яка використовується у вихідному коді додатка. Інтернаціоналізація потрібна тільки у тому випадку, якщо ці дві мови розрізняються.

> Tip|Підказка: Краще встановити англійську мову як вихідну мову додатка, так як легше знайти перекладачів із англійської мови на будь-яку іншу.

Ви можете встановити [мову додатка|CApplication::language] у
[налаштуваннях додатка](/doc/guide/basics.application#application-configuration) або
змінити його безпосередньо перед використанням можливостей інтернаціоналізації.

> Tip|Підказка: Іноді нам потрібно зчитати мову користувача із налаштувань браузера.
Ми можемо отримати ідентифікатор локалі, використовуючи [CHttpRequest::preferredLanguage].

Переклад
--------

Самою жаданою можливістю інтернаціоналізації, швидше за все, є переклад. 
Він включає у себе переклад повідомлень і рядків у представленнях. 
Перший використовується для перекладу окремих повідомлень, другий — для перекладу файлів цілком.

У процесі перекладу беруть участь обʼєкт перекладу, вихідна мова та кінцева мову. 
В Yii вихідну мову за замовчуванням прирівнюється до [вихідної мови додатка|CApplication::sourceLanguage], а
мову — до [мови додатка|CApplication::language]. Якщо обидві мови збігаються — переклад не проводиться.

### Переклад повідомлень

Переклад повідомлень здійснюється за допомогою методу [Yii::t()|YiiBase::t]. 
Метод переводить дане повідомлення з [вихідної мови додатка|CApplication::sourceLanguage] 
на [поточну мову додатка|CApplication::language].

При перекладі необхідно вказати категорію повідомлення, так як воно може мати різні переклади в різних категоріях (контекстах).
Категорія з іменем `yii` є зарезервованою для використання ядром фреймворка.

Повідомлення можуть містити параметри, які при виклику [Yii::t()|YiiBase::t] замінюються відповідними їм значеннями. 
Наприклад, наступний виклик методу замінить `{alias}` на значення відповідної змінної:

~~~
[php]
Yii::t('app', 'Path alias "{alias}" is redefined.',
	array('{alias}'=>$alias))
~~~

> Note|Примітка: повідомлення, які перекладаються, не повинні містити змінних, що змінюють рядок (`"Invalid {$message} content."`). 
Якщо є необхідність підставляти в рядок якесь значення — використовуйте параметри.

Перекладені повідомлення зберігаються в репозиторії, названому *джерело повідомлень*.
Джерело повідомлень являє собою екземпляр класу [CMessageSource] або його спадкоємця.
При виконанні [Yii::t()|YiiBase::t] проводиться пошук повідомлення в джерелі повідомлень і, 
якщо воно знайдено — повертається його перекладена версія

Yii підтримує кілька типів джерел повідомлень, перерахованих нижче.
Також ви можете створити своє джерело, успадкувавши його від [CMessageSource].

   - [CPhpMessageSource]: переклади повідомлень зберігаються як пари ключ-значення у масиві PHP. 
Початкове повідомлення при цьому є ключем, а перекладене — значенням. 
Кожен масив містить переклади для певної категорії повідомлень і знаходиться в окремому файлі, 
імʼя якого збігається з назвою категорії. Файли з перекладом для однієї і тієї ж мови зберігаються в одній директорії, 
що має таке ж імʼя, як і ідентифікатор мови. Директорії для всіх мов розташовуються в директорії, яка вказана в [basePath|CPhpMessageSource::basePath];

   - [CGettextMessageSource]: переклади повідомлень зберігаються у форматі [GNU
Gettext](http://www.gnu.org/software/gettext/);

   - [CDbMessageSource]: переклади повідомлень зберігаються у базі даних. Детальніше див. [CDbMessageSource].

Джерело повідомлень завантажується як [компонент додатка](/doc/guide/basics.application#application-component).
Повідомлення, які використовуються у додатку, зберігаються у компоненті [messages|CApplication::messages].
За замовчуванням тип даного джерела повідомлень — [CPhpMessageSource]. 
Шлях, по якому зберігаються файли перекладу — `protected/messages`.

Таким чином, для того, щоб використовувати механізм перекладу повідомлень, необхідно наступне:

   1. Викликати [Yii::t()|YiiBase::t] у потрібних місцях;

   2. Створити файли перекладу `protected/messages/IdМови/ІʼмяКатегорії.php`. Кожен такий файл просто повертає масив переведених повідомлень. Зверніть увагу, що при цьому використовується [CPhpMessageSource];

   3. У файлі конфігурації встановіть значення [CApplication::sourceLanguage] та [CApplication::language].

> Tip|Підказка: Якщо у якості джерела повідомлень використовується [CPhpMessageSource], 
для роботи з повідомленнями може використовуватися утиліта `yiic`. 
За допомогою команди `message` можливо вибрати із вихідного коду всі повідомлення, для яких необхідний переклад і, при необхідності, обʼєднати їх із уже існуючим перекладом. 
Детальний опис команди `message` можна отримати набравши у консолі `yiic help message`.

При використанні [CPhpMessageSource], повідомлення для розширень, таких, як віджет або модуль, можуть бути використані особливим чином.
Тобто, якщо повідомлення належить розширенню з іменем класу `Xyz`, то категорія повідомлень може бути вказана у форматі
`Xyz.іʼмяКатегорії`. Відповідний їй файл повідомлень буде
`ШляхДоРозширення/messages/IdМови/ІʼмяКатегорії.php`, де `ШляхДоРозширення` — директорія,
у якій знаходиться клас розширення. При використанні `Yii::t()` 
для перекладу повідомлення розширень повинен використовуватися наступний формат:

~~~
[php]
Yii::t('Xyz.іʼмяКатегорії', 'повідомлення для перекладу')
~~~

Yii підтримує [формат вибору|CChoiceFormat], відомий також як множинні форми. 
Формат вибору призначений для вибору перекладу у залежності від заданого числа.
Наприклад, в англійській мові слово 'book' може бути одиничного чи множинного числа в залежності від кількості книг.
В інших мовах слово може не мати спеціальної форми (як у китайському) або може підкорятися більш складним правилам для множини (як у українській). 
Формат вибору вирішує дану проблему простим, але в той же час ефективним способом.

Для використання формату вибору переклад повинен містити послідовність пар вираз-повідомлення,
розділених символом `|`:

~~~
[php]
'expr1#message1|expr2#message2|expr3#message3'
~~~

де `exprN` — вираз PHP, що повертає логічне значення. Якщо вираз дорівнює true —
використовується відповідний йому переклад і подальші висловлювання не обчислюються. Вираз може містити спеціальну змінну
 `n` (не `$n`!), яка містить число, передане першим параметром. Припустимо, якщо ми використовуємо переклад

~~~
[php]
'n==1#one book|n>1#many books'
~~~

і передаємо число 2 параметром [Yii::t()|YiiBase::t], то отримаємо `many books`:

~~~
[php]
Yii::t('app', 'n==1#one book|n>1#many books', array(1));
//or since 1.1.6
Yii::t('app', 'n==1#one book|n>1#many books', 1);
~~~

Якщо перевіряється відповідність певному числу, можна використовувати скорочену запис, який буде розглядатися як `n==Number`:

~~~
[php]
'1#one book|n>1#many books'
~~~

### Формат для множинних форм

З версії 1.1.6 доступний ще один механізм, який виконує переклад множинних форм слова за правилами CLDR. 
Він дозволяє використовувати більш простий запис правил, що особливо актуально для мов зі складними правилами для множинних форм слова.

Правило для множинних форм англійської мови, наведене вище, можна записати так:

~~~
[php]
Yii::t('test', 'cucumber|cucumbers', 1);
Yii::t('test', 'cucumber|cucumbers', 2);
Yii::t('test', 'cucumber|cucumbers', 0);
~~~

що дасть на виході:

~~~
cucumber
cucumbers
cucumbers
~~~

Якщо потрібно додати до повідомлення число, можна використовувати наступний код:

~~~
[php]
echo Yii::t('test', '{n} cucumber|{n} cucumbers', 1);
~~~

Тут `{n}` — спеціальний токен, який буде замінений на передане число.
В даному випадку буде надруковано `1 cucumber`.

Можна передати додаткові параметри:

~~~
[php]
Yii::t('test', '{username} has a cucumber|{username} has {n} cucumbers',
array(5, '{username}' => 'samdark'));
~~~

і навіть замінити число чим-небудь ще:

~~~
[php]
function convertNumber($number)
{
	// число прописом
	return $number;
}

Yii::t('test', '{n} cucumber|{n} cucumbers',
array(5, '{n}' => convertNumber(5)));
~~~

Кількість множинних виразів буде варіюватися залежно від мови.
Наприклад:
~~~
[php]
Yii::t('app', '{n} cucumber|{n} cucumbers', 62);
Yii::t('app', '{n} cucumber|{n} cucumbers', 1.5);
Yii::t('app', '{n} cucumber|{n} cucumbers', 1);
Yii::t('app', '{n} cucumber|{n} cucumbers', 7);
~~~

У перекладі на українську буде використано 4 вирази повідомлень замість 2:

~~~
[php]
'{n} cucumber|{n} cucumbers' => '{n} огірок|{n} огірка|{n} огірків|{n} огірка',
~~~

На виході:

~~~
62 огірка
1.5 огірка
1 огірок
7 огірків
~~~


> Info|Інформація: число і порядок виразів можна дізнатися у розділі
 [Language Plural Rules](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html#uk)
 на сайті CLDR.

### Переклад файлів

Переклад файлів здійснюється викликом [CApplication::findLocalizedFile()]. 
Параметром передається шлях до файлу, який необхідно перекласти.
Метод шукає однойменний файл у папці `LocaleID`.
Якщо файл знайдений — повертається його шлях, інакше — шлях до вихідного файлу.

Переклад файлу використовується у основному при відображенні представлень.
При виклику одного з методів відображення контролера або віджету, файли представлення будуть переведені автоматично.
Приміром, якщо [мова додатка|CApplication::language] встановлена як `zh_cn`, 
а [вихідна мова|CApplication::sourceLanguage] як `en_us`
 — при відображенні представлення `edit` буде проведений пошук представлення
`protected/views/ControllerID/zh_cn/edit.php`. 
Якщо воно знайдено — буде використана перекладена версія, якщо немає — вихідна,
що розташована у `protected/views/ControllerID/edit.php`.

Переклад файлом можна використовувати і для інших цілей. 
Наприклад, для того, щоб відобразити перекладене зображення або завантажити локалізовану версію файлу.

Форматування дати і часу
------------------------

Дата і час у різних країнах і регіонах часто форматуються по-різному. 
Завдання форматування дати і часу таким чином зводиться до генерації рядка, що підходить для даної країни та регіону. 
Для цього у Yii використовується [CDateFormatter].

Кожен екземпляр [CDateFormatter] відповідає деякій мові додатка. 
Щоб отримати форматтер для вибраної мови, ми можемо просто звернутися до властивості додатка
[dateFormatter|CApplication::dateFormatter].

Клас [CDateFormatter] містить два методи, призначених для форматування UNIX timestamp:

   - [format|CDateFormatter::format]: форматує передану у форматі UNIX timestamp дату
згідно шаблону дата-час (наприклад, `$dateFormatter->format('dd.MM.yyyy', $timestamp)`);

   - [formatDateTime|CDateFormatter::formatDateTime]: форматує передану у форматі UNIX timestamp дату
згідно шаблону, заданому для вибраної мови (наприклад формат дати `short`, формат часу `long`).

Форматування чисел
------------------

Також, як дата і час, числа можуть писатися по-різному у різних країнах і регіонах. 
Форматування чисел включає у себе форматування десяткових дробів, валют і чисел з відсотками. 
Для виконання даних завдань у Yii використовується клас [CNumberFormatter].

Для того, щоб скористатися форматтером чисел, відповідному обраній мові, ми можемо звернутися до властивості додатка [numberFormatter|CApplication::numberFormatter].

Для форматування цілих чисел і дробів у класі [CNumberFormatter] є такі методи:

   - [format|CNumberFormatter::format]: форматує число відповідно до заданого формату
(наприклад, `$numberFormatter->format('#,##0.00',$number)`);

   - [formatDecimal|CNumberFormatter::formatDecimal]: форматує число відповідно до формату, заданим для поточної мови додатка;

   - [formatCurrency|CNumberFormatter::formatCurrency]: форматує число і код валюти відповідно до формату, заданим для поточної мови додатка;

   - [formatPercentage|CNumberFormatter::formatPercentage]: форматує число відповідно до формату форматування відсотків, заданим для поточної мови додатка.